package cn.wingware.util;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import oracle.sql.CLOB;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.content.res.AXmlResourceParser;
import cn.wingware.config.SysInfoInit;
import cn.wingware.config.SysMessage;
import cn.wingware.exception.CommonUtilException;

import com.sun.org.apache.commons.beanutils.PropertyUtils;

public class CommonUtils extends PromotionUtil{
	private static final Log log = LogFactory.getLog(CommonUtils.class);
	public static int no = 1;
	public static final Object LOCK = new Object();
	
	
	public static String getBASE64(String s) {
		if (s == null)
			return null;
		return new String(Base64.encodeBase64(s.getBytes()));
	}
	public static String getFromBASE64(String s) {
		if (s == null)
			return null;
		try{
			byte[] b = Base64.decodeBase64(s.getBytes());
			return new String(b);
		}catch(Exception e) {
			return null;
		}
	}
	/**
	 * 统计指定文件中的字符的总数
	 */
	public static int getStrNum(String str,char c) {
		int i,cnt;
		cnt=0;
		char[] str_char = str.toCharArray();
		for(i=0;i<str.length(); i++)
			if(str_char [i] == c) cnt++;
		return cnt;
	}
	
	/**
	 * 从Request QueryString中获取parameter的properties
	 * 
	 * @param queryString
	 * @param charset
	 * @return
	 * @throws Exception 
	 */
	public static Properties getPropertiesFromQueryString(String queryString,
			String charset) throws Exception {
		Properties properties = new Properties();
		try {
			if (queryString == null) {
				return properties;
			}
			if (charset == null)
				charset = "UTF-8";
			String splitStrArray[] = queryString.split("&");

			for (int i = 0; i < splitStrArray.length; i++) {
				String param[] = splitStrArray[i].split("=");
				String name = param[0];
				String value = null;
				if(param.length == 1){
					value = "";
				}else{
					value = param[1];
				}
				properties.setProperty(name, URLDecoder.decode(value, charset));
			}
		} catch (Exception e) {
			throw new Exception(e);
		}
		return properties;
	}
	
	/**
	 * 从String(s1,s2,...)转为properties
	 * 
	 * @param string
	 * @param charset
	 * @return
	 * @throws Exception 
	 */
	public static Properties getPropertiesFromString(String string,String regex) throws Exception {
		Properties properties = new Properties();
		try {
			if (string == null) {
				return properties;
			}
			String splitStrArray[] = string.split(regex);

			for (int i = 0; i < splitStrArray.length; i++) {
				String name = splitStrArray[i];
				properties.setProperty(name, name);
			}
		} catch (Exception e) {
			throw new Exception(e);
		}
		return properties;
	}
	/**
	 * 生成订单号
	 * @param module_Name 模块代码
	 * @return
	 */
	public static int createOrderId() {
		synchronized (LOCK) {
			if (no >= 998) {
				no = 1;
			}
			no++;
		}
		return no;
	}
	
	/**
	 * 把由间隔符分隔的字符串(key=value&key1=value1)转换成map
	 * 
	 * @param str
	 * @return
	 */
	public static Map<String, String> string2map(String srcStr, String mark) {
		Map<String, String> map = new HashMap<String, String>();
		String tem[] = stringToArray(srcStr, mark);
		//System.out.println(tem.length);
		for (int i = 0; i < tem.length; i++) {
			String s[] = tem[i].split("=");
			// System.out.println(s[0]+":"+s[1]);
			if (s.length == 1) {
				map.put(s[0], "");
			} else if (s.length == 2) {
				map.put(s[0], s[1]);
			}
		}
		return map;
	}
	public static final String[] stringToArray(String strSource,
			String delimiter) {
		if (strSource == null)
			return null;

		// 去掉尾部分隔符
		if (strSource.substring(strSource.length() - delimiter.length()) == delimiter)
			strSource = strSource.substring(0, strSource.length()
					- delimiter.length());

		StringTokenizer token = new StringTokenizer(strSource, delimiter);
		String[] array = new String[token.countTokens()];
		int i = 0;
		// 取值
		while (token.hasMoreTokens()) {
			array[i] = token.nextToken();
			i++;
		}
		return array;
	}
	/**
	 * 
	 * 提供精确的乘法运算。
	 * 
	 * @param v1
	 *            被乘数
	 * @param v2
	 *            乘数
	 * @return 两个参数的积
	 */
	public static double mul(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.multiply(b2).doubleValue();
	}
	
	/**
	 * 截断价格保留两位
	 * @param str
	 * @param times
	 * @return
	 */
	public static String fromtPriceStr(String str,int times){
		StringBuffer sb = new StringBuffer(str);
		int dot = sb.indexOf(".");
		String st = null;
		if(dot== -1){
			st = sb.toString();
		} else {
			int len = sb.length();
			int offset = dot+times+1;
			if(len <= offset)
				st = sb.substring(0, len);
			if(len > offset)
				st = sb.substring(0, offset);
		}
		return st;
	}
	/**
	 * 按指定小数点右移位数放大Double，返回BigInteger对象
	 * 
	 * @param d
	 * @param times
	 * @return
	 */
	public static BigInteger rightDouble(Double d, int times) {
		String tmp = d.toString();
		int dot = tmp.indexOf(".");
		int length = tmp.length();
		int num = length - (dot + 1);
		StringBuffer sbf = new StringBuffer(tmp);
		sbf.deleteCharAt(dot);
		for (int i = 0; i < times - num; i++) {
			sbf.append("0");
		}
		return new BigInteger(sbf.toString());
	}
	
	/**
	 * 按指定小数点左移移位数缩小BigInteger，返回Double对象
	 * 
	 * @param d
	 * @param times
	 * @return
	 */
	public static Double leftDouble(BigInteger in, int times) {
		String tmp = in.toString();
		int length = tmp.length();
		String str1 = null;
		String str2 = null;
		StringBuffer result = new StringBuffer("");
		if (length > times) {
			str1 = tmp.substring(0, length - times);
			str2 = tmp.substring(length - times, length);
			result.append(str1);
			result.append(".");
			result.append(str2.length() >= 2 ? str2.subSequence(0, 2) : str2);
		} else {
			result.append("0.");
			for (int i = 0; i < times - length; i++) {
				result.append("0");
			}
			result.append(tmp);
			if (result.length() > 3) {
				result.delete(4, result.length());
			}
		}
		return new Double(result.toString());
	}
	
	
	/**
	 * 读取配置文件
	 * @param 文件路径（格式：/com/lenovo/XXX）
	 * @return 资源对象
	 */
	public static Properties getProperties(String path) throws Exception{
		//InputStream in = ClassLoader.getSystemResourceAsStream(path);
		InputStream in = CommonUtils.class.getResourceAsStream(path);
		Properties properties = new Properties();
		try {
			properties.load(in);
		} catch (IOException e) {
			log.error("读取配置文件出错：",e);
			throw new Exception(e);
		}
		return properties;
	}

	/**
	 * 读取App 应用的包名(适用于jar文件)
	 * 
	 * @param filePath
	 * @return App 应用的包名
	 */
	public  static String getPackageName(String filePath) {
		if (filePath == null || filePath.equals("")
				|| !filePath.endsWith(".jar")) {
			return null;
		}
		try {
			JarFile jf = new JarFile(filePath);
			Manifest mf = jf.getManifest();
			Attributes attributes = mf.getMainAttributes();
			return attributes.getValue("Main-Class");
		} catch (IOException e) {
			return null;
		}
	}

	/**
	 * 读取App 应用的包名(适用于apk,lca文件)
	 * 
	 * @param filePath 应用文件路径
	 * @param rootPath 存放文件的绝对路径
	 * @return App 应用的包名
	 * @throws XmlPullParserException
	 * @throws IOException
	 */
	public static String getPackageNameFromAxml(String filePath,String rootPath)throws XmlPullParserException, IOException {
		AXmlResourceParser parser = new AXmlResourceParser();
		InputStream xmlfile = getXmlStream(filePath,rootPath);
		parser.open(xmlfile);

		while (true) {
			int type = parser.next();
			if (type == XmlPullParser.END_DOCUMENT) {
				break;
			}
			switch (type) {
			case XmlPullParser.START_TAG: {
				for (int i = 0; i != parser.getAttributeCount(); ++i) {
					String pak = parser.getAttributeName(i);
					if (pak.equals("package")) {
						String packageName = parser.getAttributeValue(i);
						log.debug("Read Android package name from apk file,package name is : "+ packageName);
						return packageName;
					}
				}
				break;
			}
			default:
				break;
			}
		}
		return null;
	}
	
	/**
	 * 读取App 应用的版本名称(适用于apk,lca文件)
	 * 
	 * @param filePath 应用文件路径
	 * @param rootPath 存放文件的绝对路径
	 * @return App 应用的版本名称
	 * @throws XmlPullParserException
	 * @throws IOException
	 */
	public static String getVersionNameFromAxml(String filePath,String rootPath)throws XmlPullParserException, IOException {
		AXmlResourceParser parser = new AXmlResourceParser();
		InputStream xmlfile = getXmlStream(filePath,rootPath);
		parser.open(xmlfile);

		while (true) {
			int type = parser.next();
			if (type == XmlPullParser.END_DOCUMENT) {
				break;
			}
			switch (type) {
			case XmlPullParser.START_TAG: {
				for (int i = 0; i != parser.getAttributeCount(); ++i) {
					String pak = parser.getAttributeName(i);
					if (pak.equals("versionName")) {
						String versionName = parser.getAttributeValue(i);
						log.debug("Read Android version name from apk file,versionName is : "+ versionName);
						return versionName;
					}
				}
				break;
			}
			default:
				break;
			}
		}
		return null;
	}
	
	/**
	 * 读取App 应用的版本号(适用于apk,lca文件)
	 * 
	 * @param filePath 应用文件路径
	 * @param rootPath 存放文件的绝对路径
	 * @return App 应用的版本号
	 * @throws XmlPullParserException
	 * @throws IOException
	 */
	public static String getVersionCodeFromAxml(String filePath,String rootPath)throws XmlPullParserException, IOException {
		AXmlResourceParser parser = new AXmlResourceParser();
		InputStream xmlfile = getXmlStream(filePath,rootPath);
		parser.open(xmlfile);

		while (true) {
			int type = parser.next();
			if (type == XmlPullParser.END_DOCUMENT) {
				break;
			}
			switch (type) {
			case XmlPullParser.START_TAG: {
				for (int i = 0; i != parser.getAttributeCount(); ++i) {
					String pak = parser.getAttributeName(i);
					if (pak.equals("versionCode")) {
						String versionCode = AXMLPrinter.getAttributeValue(parser, i);
						log.debug("Read Android version name from apk file,versionCode is : "+ versionCode);
						return versionCode;
					}
				}
				break;
			}
			default:
				break;
			}
		}
		return null;
	}
	
	/**
	 * 读取App 应用的详细信息(适用于apk,lca文件)
	 * 
	 * @param filePath 应用文件路径
	 * @param rootPath 存放文件的绝对路径
	 * @return App 详细信息
	 * @throws XmlPullParserException
	 * @throws IOException
	 */
	public static Map<String,String> getAppInfoFromAxml(String filePath,String rootPath)throws XmlPullParserException, IOException {
		Map<String,String> result = new HashMap<String,String>();
		AXmlResourceParser parser = new AXmlResourceParser();
		InputStream xmlfile = getXmlStream(filePath,rootPath);
		parser.open(xmlfile);

		while (true) {
			int type = parser.next();
			if (type == XmlPullParser.END_DOCUMENT) {
				break;
			}
			switch (type) {
			case XmlPullParser.START_TAG: {
				for (int i = 0; i != parser.getAttributeCount(); ++i) {
					String pak = parser.getAttributeName(i);
					System.out.println("name : "+pak+" value: "+parser.getAttributeValue(i));
					
					if (pak.equals("package")) {
						String packageName = parser.getAttributeValue(i);
						log.debug("Read Android package name from apk file,package name is : "+ packageName);
						result.put("packageName", packageName);
					}
					if (pak.equals("versionName")) {
						String versionName = parser.getAttributeValue(i);
						log.debug("Read Android version name from apk file,versionName is : "+ versionName);
						result.put("versionName", versionName);
					}
					if (pak.equals("versionCode")) {
						String versionCode = AXMLPrinter.getAttributeValue(parser, i);//parser.getAttributeValue(i);
						log.debug("Read Android version code from apk file,versionCode is : "+ versionCode);
						result.put("versionCode", versionCode);
					}
				}
				break;
			}
			default:
				break;
			}
		}
		return result;
	}
	
	/**
	 * 通过USS模块获取userId
	 * @param request
	 * @param response
	 * @return
	 */
	public static long getUserIdfromUSS(HttpServletRequest request,HttpServletResponse response) throws CommonUtilException {
		//单元测试打桩
		if(SysInfoInit._UNIT_TEST_FLAG_!=null) {
			return new Long(System.getProperty("userId")).longValue();
		}
		//check Cookies is exist or not 
		String cookie = "";
		Cookie cks[] = request.getCookies();
        if(cks != null)
        {
            Cookie acookie[];
            int j = (acookie = cks).length;
            for(int i = 0; i < j; i++)
            {
                Cookie ck = acookie[i];
                log.debug((new StringBuilder("cookie name :")).append(ck.getName()).toString());
                log.debug((new StringBuilder("cookie value :")).append(ck.getValue()).toString());
                if(!ck.getName().toUpperCase().equals("LPSUST") || ck.getValue().length() == 0)
                    continue;
                cookie = ck.getValue();
                log.debug((new StringBuilder("found cookie in cookies : ")).append(cookie).toString());
                break;
            }
        }
        //USS get UserInfo begin
		/*String lpsust = request.getParameter("lpsust");
		if(lpsust != null){
			Cookie cookieName = new Cookie("lpsust",lpsust);
			log.debug("Lpsust url parameter is not null,create cookie!");
			cookieName.setMaxAge(SysInfoInit.AMS_COOKIE_MAXAGE);
			response.addCookie(cookieName);
		}else{
			log.debug("Lpsust url parameter is null,not create cookie!");
		}*/
		//long  userId = LPSIdentityInfo.getUserID(request);
		//USS get UserInfo end
		long  userId = -1L;
//		TODO:需要实现 ticket
//		UserTicketInfo ticketInfo = LpsIdentityInfo.getUserTicketInfo(request);
//		if(ticketInfo != null)
//			userId = ticketInfo.getID();
		return userId;
	}
	
	
	/**
	 * 获取Cookie值
	 * @param request
	 * @param response
	 * @param cookieName
	 * @return Cookie值
	 * @throws CommonUtilException
	 */
	public static String getValueFromCookie(HttpServletRequest request,HttpServletResponse response,String cookieName) throws CommonUtilException {
		String cookie = "";
		Cookie cks[] = request.getCookies();
        if(cks != null){
            Cookie acookie[];
            int j = (acookie = cks).length;
            for(int i = 0; i < j; i++){
                Cookie ck = acookie[i];
                log.debug((new StringBuilder("cookie name :")).append(ck.getName()).toString());
                log.debug((new StringBuilder("cookie value :")).append(ck.getValue()).toString());
                if(!ck.getName().equalsIgnoreCase(cookieName) || ck.getValue().length() == 0)
                    continue;
                cookie = ck.getValue();
                log.debug((new StringBuilder("found cookie in cookies : ")).append(cookie).toString());
                break;
            }
        }
        return cookie;
	}
	/**
	 * 判断文件夹是否存在不存字则创建
	 * @param dirs 
	 * @throws Exception
	 */
	public static boolean creatDirifNotExist(String dirs) throws Exception{
		File loadFile = new File(dirs);
		if(!loadFile.exists()){
			return loadFile.mkdirs();
		}
		return false;
	}
	
	/**
	 * 关键字符过滤
	 * @param 要替换的字符串
	 * @param 要替换的字符
	 * @return 过滤后的内容
	 */
	public static String replaceComment(String str,String replaceStr) throws Exception{
		if(replaceStr != null && !replaceStr.trim().equals("")){
			String [] reStr = replaceStr.split(",");
			for(String ss : reStr){
				str = str.replaceAll("\\*", ss);
				log.debug("str:"+str);
			}
		}
		return str;
	}
	
	/**
	 * 为jsp添加Header
	 * @param response
	 * @param mCacheTime
	 */
	public static void setHeader(HttpServletResponse response,Long mCacheTime) {
		//response.addHeader("expires", "28 Oct 2010 10:28:40 GMT");
		final long now = System.currentTimeMillis();
		response.addHeader(SysMessage.CACHE_CONTROL_HEADER,SysMessage.MAX_AGE_VALUE+mCacheTime.longValue());
		response.addHeader(SysMessage.CACHE_CONTROL_HEADER,SysMessage.PRE_CHECK_VALUE+mCacheTime.longValue());
		response.addHeader(SysMessage.CACHE_CONTROL_HEADER,SysMessage.POST_CHECK_VALUE+mCacheTime.longValue());
		response.addHeader(SysMessage.LAST_MODIFIED_HEADER, SysMessage.httpDateFormat.format(new Date(now)));
		log.debug("CurrentTime:"+SysMessage.httpDateFormat.format(new Date(now)));
		response.addHeader(SysMessage.EXPIRES_HEADER, SysMessage.httpDateFormat.format(new Date(now +mCacheTime.longValue() * SysMessage.MILLISECONDS_IN_SECOND)));
		log.debug("ExpiresTime:"+SysMessage.httpDateFormat.format(new Date(now +mCacheTime.longValue() * SysMessage.MILLISECONDS_IN_SECOND)));
	}
	
	/**
	 * 获取apk文件中的AndroidManifest.xml文件流
	 * 
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	private static InputStream getXmlStream(String filePath,String rootPath) throws IOException {
		File file1 = new File(filePath);
		JarFile zipfile = new JarFile(file1);
		//清空缓冲区
		String cachePath = rootPath + SysInfoInit.AMS_APP_FILECACHE;
		File cacheFile = new File(cachePath); 
		if (cacheFile.exists()) {
			deleteAllFile(cachePath);
		}
		Enumeration enumeration = zipfile.entries();
		JarEntry zipEntry = null;
		while (enumeration.hasMoreElements()) {
			zipEntry = (JarEntry) enumeration.nextElement();
			String name = zipEntry.getName();
			String loadFilePath = cacheFile+"/"+name;
			File loadFile = new File(loadFilePath);
			if (zipEntry.isDirectory()) {
				loadFile.mkdir();
			} else {
				if (!loadFile.getParentFile().exists()) {
					loadFile.getParentFile().mkdirs();
				}
				if (name.indexOf(".apk") > -1) {
					log.debug(loadFilePath);
					OutputStream out = new FileOutputStream(loadFile);
					InputStream in = zipfile.getInputStream(zipEntry);//  zipfile.getInputStream(zipEntry);
					byte b[] = new byte[1024];
					int length;
					while ((length = in.read(b)) > 0) {
						out.write(b, 0, length);
					}
					out.close();
					in.close();
					return getXmlStream(loadFilePath,rootPath);
				}
			}
			if (name.equals("AndroidManifest.xml") && !zipEntry.isDirectory()) {
				return zipfile.getInputStream(zipEntry);
			}
		}
		return null;
	}

	/**
	 * 获取apk文件中的AndroidManifest.xml文件流
	 * 
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	private static InputStream getXmlStream(String filePath,String rootPath,String fileName) throws IOException {
		File file1 = new File(filePath);
		JarFile zipfile = new JarFile(file1);
		//清空缓冲区
		String cachePath = rootPath + SysInfoInit.AMS_APP_FILECACHE;
		File cacheFile = new File(cachePath); 
		if (cacheFile.exists()) {
			deleteAllFile(cachePath);
		}
		Enumeration enumeration = zipfile.entries();
		JarEntry zipEntry = null;
		while (enumeration.hasMoreElements()) {
			zipEntry = (JarEntry) enumeration.nextElement();
			String name = zipEntry.getName();
			String loadFilePath = cacheFile+"\\"+name;
			File loadFile = new File(loadFilePath);
			if (zipEntry.isDirectory()) {
				loadFile.mkdir();
			} else {
				if (!loadFile.getParentFile().exists()) {
					loadFile.getParentFile().mkdirs();
				}
			}
			if (name.equals(fileName) && !zipEntry.isDirectory()) {
				return zipfile.getInputStream(zipEntry);
			}
		}
		return null;
	}
	// 删除文件夹下的所有文件
	private static boolean deleteAllFile(String path) {
		boolean ret = false;
		File file = new File(path);
		if (file.exists()) {
			if (file.isDirectory()) {
				File[] fileList = file.listFiles();
				for (int i = 0; i < fileList.length; i++) {
					String filePath = fileList[i].getPath();
					deleteAllFile(filePath);
				}
			} else if (file.isFile()) {
				file.delete();
			}
		}
		return ret;
	}
	
	public static String coculateByte(long byteSize){
		double bsize = Double.parseDouble(byteSize+"");
		double ksize = bsize/1024;
		double msize = ksize/1024;
		double gsize = 0.0;
		log.debug("bsize :"+bsize);
		log.debug("ksize :"+ksize);
		log.debug("msize :"+msize);
		log.debug("gsize :"+gsize);
		DecimalFormat formater = new DecimalFormat(SysMessage.AMS_DOUBLEFOMRAT_COCULATEBYTE);
		
		String result = null;
		if(ksize < 1){
			result =  byteSize+"B";
		}else if(ksize >=1 && ksize < 512){
			result = exceptZero(formater.format(ksize))+"KB";
		}else if(ksize >= 512 && msize < 512){
			result =  exceptZero(formater.format(msize))+"MB";
		}else if(msize >= 512){
			gsize = msize/1024;
			result =  exceptZero(formater.format(gsize))+"GB";
		}
		return result;
	}
	
	
	private static String exceptZero(String st){
		if(st.lastIndexOf("0") == st.length()-1){
			st = st.substring(0,st.length()-1);
			return exceptZero(st);
		}
		if(st.lastIndexOf(".") == st.length()-1){
			st = st.substring(0,st.length()-1);
		}
		return st;
	}
	public static String clob2String(CLOB clob) throws Exception {
		return (clob != null ? clob.getSubString(1, (int) clob.length()) : null);
	}
	/**
	 *  将Blob值转换成String类型
	 *  @param blobValue 待转换值
	 *  @return String
	 */
	public static String blob2String(oracle.sql.BLOB blobValue) throws Exception{
		StringBuffer stringbuffer = new StringBuffer();
		String tempSTR = "";
		if(blobValue != null){
			BufferedReader bf = new BufferedReader(new InputStreamReader(blobValue.getBinaryStream()));
			while((tempSTR = bf.readLine()) != null){
				stringbuffer.append(tempSTR);
			}
			/*String content = new String(blobValue.getBytes(),"GBK");
			stringbuffer.append(content);*/
		}
		return stringbuffer.toString();
	}

	public static String toStringBuilder(Object obj) {
		StringBuffer buff;
		Object value;
		buff = new StringBuffer("");
		value = null;
		if (obj == null)
			return "[null]";
		try {
			buff.append((new StringBuilder()).append("\n[").append(
					obj.getClass()).toString());
			java.beans.PropertyDescriptor origDescriptors[] = PropertyUtils.getPropertyDescriptors(obj);
			for (int i = 0; i < origDescriptors.length; i++) {
				String name = origDescriptors[i].getName();
				String type = origDescriptors[i].getPropertyType().getName();
				if ("class".equals(name))
					continue;
				if (PropertyUtils.isReadable(obj, name))
					value = PropertyUtils.getSimpleProperty(obj, name);
				buff.append("\n |-");
				if (isPrintable(type)) {
					buff.append((new StringBuilder()).append(name).append(":")
							.append(value).toString());
					continue;
				}
				if (value == null)
					buff.append((new StringBuilder()).append(name).append(
							":null").toString());
				else
					buff.append((new StringBuilder()).append(name).append(":")
							.append(type).toString());
			}

			buff.append("\n]");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return buff.toString();
	}

	/**
	 * 判断指定属性类型的值是否允许打印
	 * @param type 属性类型
	 * @return true/false(true:允许打印；false:不允许打印；)
	 */
	private static boolean isPrintable(String type) {
		if ("byte".equals(type) 
				|| "short".equals(type) 
				|| "int".equals(type)
				|| "long".equals(type) 
				|| "float".equals(type)
				|| "double".equals(type) 
				|| "char".equals(type)
				|| "boolean".equals(type)
			)
			return true;
		if ("java.lang.Byte".equals(type) 
				|| "java.lang.Short".equals(type)
				|| "java.lang.Integer".equals(type)
				|| "java.lang.Long".equals(type)
				|| "java.lang.Float".equals(type)
				|| "java.lang.Double".equals(type)
				|| "java.lang.Character".equals(type)
				|| "java.lang.Boolean".equals(type)
			)
			return true;
		if ("java.lang.String".equals(type) 
				|| "java.util.Date".equals(type)
			)
			return true;
		else
			return false;
	}
	/**
	 * 取得客户端IP地址
	 * 
	 * 假如通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串ip值， 究竟哪个才是真正的用户端的真实IP？
	 * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。 如：X-Forwarded-
	 * For：192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100, 用户真实IP为：
	 * 192.168.1.110
	 * 
	 * @param request
	 * @return String
	 * @author huohezhang
	 * @time 2010-9-21
	 */
	public static String getIpAddr(HttpServletRequest request) {
		//单元测试打桩
		if(SysInfoInit._UNIT_TEST_FLAG_!=null) 
			return System.getProperty("ip");	
		
        String ip = request.getHeader("X-Forwarded-For");
        
        log.debug("Get ip address from header 'X-Forwarded-For' is :"+ip);
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
            log.debug("Get ip address from header 'Proxy-Client-IP' is :"+ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
            log.debug("Get ip address from header 'WL-Proxy-Client-IP' is :"+ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
            log.debug("Get ip address from header 'HTTP_CLIENT_IP' is :"+ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            log.debug("Get ip address from header 'HTTP_X_FORWARDED_FOR' is :"+ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            log.debug("Get ip address from RemoteAddr() is :"+ip);
        }
        if(ip!=null){
        	if(ip.contains(",")){
        		ip = ip.substring(0,ip.indexOf(","));
        	}
        	
        	if(ip.length()>23){
        		ip = ip.substring(0,23);
        	}
	     }
        log.debug("Get ip address is :"+ip);
        return ip;
    }
	/*
	 * 获得用户昵称
	 */
	public static String getNickName(String userId) {
		//单元测试打桩
		if(SysInfoInit._UNIT_TEST_FLAG_!=null) 
			return System.getProperty("nickname");	
		
		String name=HttpUtil.GetUrl(SysInfoInit.AMS_USERCOMMENT_GETNICKNAME+userId,null);
        log.debug("Get User NickName is :"+name);
        return name;
    }
	
	/**
	 * Double数字四舍五入
	 * 
	 * @param doubleValue
	 * @param scale
	 * @return
	 */
	public static Double round(Double doubleValue, int scale) {
		Double flag = null;
		String text = doubleValue.toString();
		BigDecimal bd = new BigDecimal(text).setScale(scale,
				BigDecimal.ROUND_HALF_UP);
		flag = bd.doubleValue();
		if(flag < 0.01){
			flag =0.01;
	    }
		return flag;
	}
	
//	/**
//	 *  初始化消息发送队列名称 add by suiyongxin 
//	 */
//	public static void initQueueInfo(JdbcTemplate jdbcT)throws LpsAmsException{
//		List<Map<String,Object>> messageQueusList = null;
//		String spliter = ",";
//		String _DOWNLOAD_QUEUE ="";
//		String _COMMENT_QUEUE ="";
//		String _GRADE_QUEUE ="";
//		String _UPSHELL_QUEUE ="";
//		String _PURCHASE_QUEUE ="";
//		try{
//			//messageQueusList = amsDao.getAmsQueueInfo();
//			StringBuffer sbSQL = new StringBuffer();
//			sbSQL.append("select * from ams_queue ");
//			messageQueusList=jdbcT.queryForList(sbSQL.toString());
//			
//			log.info("-------------------【AMS"+"子系统】开始初始化评论，评分，下载，初始化消息队列名称常量！----------------------");
//			if(messageQueusList != null && !messageQueusList.isEmpty()){
//				for(Map<String,Object> map: messageQueusList){
//					switch(Integer.parseInt(String.valueOf(map.get("type")))){
//					
//						case 1:
//							_DOWNLOAD_QUEUE +=spliter+String.valueOf(map.get("qname"));
//							break;
//						case 2:
//							_COMMENT_QUEUE +=spliter+String.valueOf(map.get("qname"));
//							break;
//						case 3:
//							_GRADE_QUEUE +=spliter+String.valueOf(map.get("qname"));
//							break;
//						case 4:
//							_UPSHELL_QUEUE +=spliter+String.valueOf(map.get("qname"));
//							break;
//						case 5:
//							_PURCHASE_QUEUE +=spliter+String.valueOf(map.get("qname"));
//							
//					}
//				}
//				/*赋值*/    /** 评论，评分，下载发消息通知，消息队列信息*/
//				if(_DOWNLOAD_QUEUE.length()>0)
//					JMSUtils.APPSTORE_DOWNLOAD_QUEUE =_DOWNLOAD_QUEUE.substring(1);
//				if(_COMMENT_QUEUE.length()>0)
//					JMSUtils.APPSTORE_COMMENT_QUEUE =_COMMENT_QUEUE.substring(1);
//				if(_GRADE_QUEUE.length()>0)
//					JMSUtils.APPSTORE_GRADE_QUEUE = _GRADE_QUEUE.substring(1);
//				if(_UPSHELL_QUEUE.length()>0)
//					JMSUtils.APPSTORE_UPSHELL_QUEUE= _UPSHELL_QUEUE.substring(1);
//				if(_PURCHASE_QUEUE.length()>0)
//					JMSUtils.APPSTORE_PURCHASE_QUEUE= _PURCHASE_QUEUE.substring(1);
//				log.info("JMSUtils.APPSTORE_DOWNLOAD_QUEUE:"+JMSUtils.APPSTORE_DOWNLOAD_QUEUE);
//				log.info("JMSUtils.APPSTORE_COMMENT_QUEUE"+JMSUtils.APPSTORE_COMMENT_QUEUE);
//				log.info("JMSUtils.APPSTORE_GRADE_QUEUE"+JMSUtils.APPSTORE_GRADE_QUEUE);
//				log.info("JMSUtils.APPSTORE_UPSHELL_QUEUE"+JMSUtils.APPSTORE_UPSHELL_QUEUE);
//				log.info("JMSUtils.APPSTORE_PURCHASE_QUEUE"+JMSUtils.APPSTORE_PURCHASE_QUEUE);
//				
//			    
//			}else{
//				log.info("-------------------【AMS"+"子系统】初始化评论，评分，下载，初始化消息队列名称常量失败，队列参数未配置！");
//			}
//		}catch(Exception ex){
//			throw new LpsAmsException("【AMS"+"子系统】初始化评论，评分，下载，初始化消息队列名称常量失败！",ex); 
//		}
//	}
	
	/**
	 * 通过startIndex，count 计算当前页
	 * @param startIndex
	 * @param count
	 * @return
	 */
	public static int getCurrentPage(int startIndex,int count){
		if(startIndex<=count){
			return 1;
		}else{
			return (startIndex-1)/count + 1;
		}
		
	}
	
	/**
	 * add by suiyx
	 * 将查询出的应用列表转换成包含指定数据的列表 :
	 * 	target
		appname
		app_version
		ispay
		app_price
		icon_addr
		app_publishdate
		star_level
		package_name
		app_size
		discount
	 * @return 
	 */
	public static List<?> convertApplist(List<Map<String,Object>> appList)throws Exception{
		List<Map<String,Object>> newApplist = new ArrayList<Map<String,Object>>();
		for(Map<String, Object>  map : appList){
			Map<String, Object> temp = new HashMap<String,Object>();
			temp.put("addv", map.get("addv"));
			temp.put("target", "app");
			temp.put("appname", map.get("appname"));
			temp.put("app_version", map.get("app_version"));
			temp.put("app_versioncode", map.get("app_versioncode"));
			temp.put("ispay", map.get("ispay"));
			temp.put("app_price", map.get("app_price"));
			temp.put("icon_addr", map.get("icon_addr"));
			if(!StringUtils.isEmpty(String.valueOf(map.get("app_publishdate")))){
				temp.put("app_publishdate", DateUtil.praseString2Date(String.valueOf(map.get("app_publishdate"))).getTime());
			}else{
				temp.put("app_publishdate", null);
			}
			temp.put("star_level", map.get("star_level"));
			temp.put("package_name", map.get("package_name"));
			temp.put("app_size", map.get("app_size"));
			temp.put("discount", map.get("discount"));
        	newApplist.add(temp);
        }
		return newApplist;
	}
	/**
	 * Double数字截断
	 * 
	 * @param doubleValue
	 * @param scale
	 * @return
	 */
	public static Double roundTruncate(Double price ,Double discount) {
		double flag = ((int)(price * discount *100))/100d;
		log.debug("flag value is :"+flag);
		if(flag < 0.01){
			flag =0.01;
	    }
		log.debug("Get the price of app after amsutil discount compare 0.01 is:" + flag);
		return flag;
	}
	/**
	 * 返回json错误信息
	 * @param response
	 * @param statusCode
	 * @param errorCode
	 * @param detail
	 * @throws Exception 
	 */
	public static void sendErrorJsonInfo(HttpServletResponse response,int statusCode,String errorCode,String detail) throws Exception{
		JsonErrorInfo err = new JsonErrorInfo();
		err.setCode(errorCode);
		err.setTimestamp(new Timestamp(System.currentTimeMillis()));
		err.setDetail(detail);
		log.debug("JsonErrorInfo:---------");
		log.debug("errorCode:"+errorCode);
		log.debug("timestamp :"+err.getTimestamp());
		log.debug("detail :"+err.getDetail());
		log.debug("statusCode :"+statusCode);
		
		//String writer = buildJsonErrorInfo(err);
		log.debug("ErrorXmlInfo : "+err.toJsonString());
		response.setContentType(SysMessage.AMS_CONTENT_TYPE_HTML);
		response.getWriter().write(err.toJsonString());
		response.setStatus(statusCode);
	}
	
	
	public static String getNickNameByUseridFromSNS(long userId) {
		HttpURLConnection httpURLConnection = null;
		String URLName = SysInfoInit.AMS_USERCOMMENT_GETNICKNAME;
		log.debug("用户评论获取昵称请求URL：" + URLName);
		String nickName = SysMessage.AMS_MESSAGE_NICKNAME_NULL;
		try {
			httpURLConnection = (HttpURLConnection) new URL(URLName).openConnection();
			httpURLConnection.setConnectTimeout(10000);
			httpURLConnection.setReadTimeout(10000);
			// Properties prop = System.getProperties();
			// 设置http访问要使用的代理服务器的地址
			// prop.setProperty("http.proxyHost","10.99.60.201");
			// 设置http访问要使用的代理服务器的端口
			// prop.setProperty("http.proxyPort","8080");
			// 设置连接属性
			// httpURLConnection.setDoOutput(true);
			httpURLConnection.setDoInput(true);
			httpURLConnection.setUseCaches(false);
			// 因为这个是post请求，设立需要设置为true
			httpURLConnection.setDoOutput(true);
			// 设置以POST方式
			httpURLConnection.setRequestMethod("POST");
			// Post请求不能使用缓存
			httpURLConnection.setInstanceFollowRedirects(true);
			DataOutputStream out = new DataOutputStream(httpURLConnection.getOutputStream());
			// 要上传的参数
			String content = "{\"uids\":[" + userId + "]}";
			// 将要上传的内容写入流中
			out.writeBytes(content);
			// 刷新、关闭
			out.flush();
			out.close();
			InputStream in = httpURLConnection.getInputStream();
			byte[] b = new byte[in.available()];
			in.read(b);
			String jsonData = new String(b);
			log.debug("[" + URLName + "]获取json数据为:" + jsonData);
			JSONObject jsonObject = JSONObject.fromObject(jsonData);
			if (jsonObject != null) {
				jsonObject = jsonObject.getJSONObject("result");
				if (jsonObject != null) {
					JSONArray array = jsonObject.getJSONArray("nns");
					if (array == null || array.size() < 1) {
						nickName = SysMessage.AMS_MESSAGE_NICKNAME_NULL;
						log.debug("key('nns')[" + jsonData + "]get JSONObject[nns] is null!没有从USS获取到用户[" + userId + "]昵称，默认取值为:" + nickName);
					} else {
						String name = null;
						int size = array.size();
						for (int i = 0; i < size; i++) {
							jsonObject = (JSONObject) array.get(i);
							if (jsonObject != null && (jsonObject.get("uid") + "").equals(userId + "")) {
								name = jsonObject.getString("nn");
								break;
							}
						}
						if (StringUtils.isEmpty(name)) {
							nickName = SysMessage.AMS_MESSAGE_NICKNAME_NULL;
							log.debug("没有从USS获取到用户[" + userId + "]昵称，默认取值为:" + nickName);
						}else{
							nickName = name;
						}
						log.debug("从USS获取到的用户[" + userId + "]昵称:" + nickName);
					}
				} else {
					nickName = SysMessage.AMS_MESSAGE_NICKNAME_NULL;
					log.debug("key('result')[" + jsonData + "]to JSONObject is null,没有从USS获取到用户[" + userId + "]昵称，默认取值为:" + nickName);
				}
			} else {
				nickName = SysMessage.AMS_MESSAGE_NICKNAME_NULL;
				log.debug("[" + jsonData + "]to JSONObject is null,没有从USS获取到用户[" + userId + "]昵称，默认取值为:" + nickName);
			}
		} catch (JSONException e) {
			log.error("获取json数据格式异常：", e);
		} catch (MalformedURLException e) {
			log.error("获取昵称出错，出错信息为：", e);
		} catch (java.net.ConnectException e) {
			log.error("获取昵称出错，无法打开Http连接 ：", e);
		} catch (IOException e) {
			log.error("获取昵称服务端出错，出错信息为：", e);
		} finally {
			httpURLConnection.disconnect();
		}
		return nickName;
	}

	/**
	 * 如我的UserId=10000000252,我的头像就是：
     * /sns/images/data/avatar/010/000/000/252_small.jpg;
     * 
     * http://snspic.dev.surepush.cn/snsimg/pic/get/010000000158
	 * 兼容一期：
	 * http://snspic.dev.surepush.cn/snsimg/images/data/avatar/010/000/000/158_small.jpg
     * 
	 * 获取头像
	 * @param userId
	 * @return
	 */
	public static String getFaceUrl(long userId){
		return SysInfoInit.LEYOU_FACE_URL+"/snsimg/pic/get/0"+userId;
	}
	
	
	public static void main(String[] args) throws Exception {
		System.out.println(getStrNum("1,2,3,33,",'?'));
	    System.out.println("transfer time is :"+System.currentTimeMillis() );
	    System.out.println(DateUtil.praseString2Date(String.valueOf(null)).getTime());
	}
}
